package org.exhibitj.operators;

import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.List;
import org.exhibitj.automation.Action;
import org.exhibitj.automation.Agent;
import org.exhibitj.defect.Defect;
import org.exhibitj.operators.matchers.Matcher;
import org.exhibitj.operators.matchers.NamedControlMatcher;

public class ListOperator extends ControlOperator {
	private List list;

	public ListOperator(ShellOperator shell, NamedControlMatcher<List>... matchers) {
		super(shell);
		list = shell.findWidget(List.class, matchers);
	}

	@Override
	protected Control getControl() {
		return list;
	}

	public void select(String text) {
		checkIsVisible();

		askAgentTo(selectItemWith(text));
		shell.waitForEvents();
	}

	private Action selectItemWith(final String text) {
		return new Action() {
			@Override
			public void perform(Agent agent) {
				list.select(list.indexOf(text));
			}
		};
	}

	public void hasSelection(Matcher<String[]> expected) {
		String[] actual = SWTDisplayThread.fetch(fetchSelectedItems());
		if (!expected.isMatch(actual)) {
			throw new MismatchSelectionDefect("Selection mismatch " + expected.describe(actual));
		}
	}

	private FetchingRunnable<String[]> fetchSelectedItems() {
		return new FetchingRunnable<String[]>() {
			@Override
			public String[] fetchValue() {
				LOG.info("Selected strings on list");
				return list.getSelection();
			}
		};
	}

	@SuppressWarnings("serial")
	class MismatchSelectionDefect extends Defect {
		MismatchSelectionDefect(String explanation) {
			super(explanation);
		}
	}
}
